﻿#include "solverPerformance.hpp"

#include <iomanip>

bool UNAP::SolverPerformance::checkConvergence(const scalar Tolerance,
                                               const scalar RelTolerance,
                                               const int minIter) {
  if ((finalResidual_ < Tolerance ||
       (RelTolerance > VSMALL &&
        finalResidual_ <= RelTolerance * initialResidual_)) &&
      nIterations_ >= minIter) {
    converged_ = true;
  } else {
    converged_ = false;
  }

  return converged_;
}

bool UNAP::SolverPerformance::checkConvergence(const scalar Tolerance,
                                               const int minIter) {
  if ((finalResidual_ < Tolerance) && nIterations_ >= minIter) {
    converged_ = true;
  } else {
    converged_ = false;
  }

  return converged_;
}

bool UNAP::SolverPerformance::checkConvergence(const scalar Tolerance,
                                               const scalar RelTolerance) {
  if ((finalResidual_ < Tolerance ||
       (RelTolerance > VSMALL &&
        finalResidual_ <= RelTolerance * initialResidual_))) {
    converged_ = true;
  } else {
    converged_ = false;
  }

  return converged_;
}

bool UNAP::SolverPerformance::checkSingularity(const scalar residual) {
  if (residual >= VSMALL) {
    singular_ = false;
  } else {
    singular_ = true;
  }

  return singular_;
}
void UNAP::SolverPerformance::printResidual(int precision) {
  std::cout.flags(std::ios::left);
  std::cout.flags(std::ios::showpoint);
  COUT << "At nIter = ";
  std::cout.width(5);
  COUT << this->nIterations() << " , res = ";
  std::cout.width(precision + 2);
  std::cout.precision(precision);
  COUT << this->finalResidual()
       << " , rel res = " << this->finalResidual() / this->initialResidual();
  std::cout.precision(precision / 2);
  COUT << " , conv rate = " << this->finalResidual() / this->previousResidual()
       << ENDL;
}
